package Simulator;

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;

import Shared.AmbType;
import Shared.MapPosition;
import Shared.MsgType;
import Shared.RadioManager;
import Shared.RadioMessage;

/**
 * The Radio module, see Architecture report for specifications.
 */

public class Radio {

	private RadioManager rm;
	private BlockingQueue<RadioMessage> receivingQueue;
	private int ambID;

	/**
	 * Create a Radio for the ambulance with ID "ambID"
	 * 
	 * @param ambID
	 *            the ID of the Radio's ambulance
	 */
	public Radio(int ambID) {
		this.rm = RadioManager.getInstance();
		this.receivingQueue = new LinkedBlockingQueue<RadioMessage>();
		this.ambID = ambID;
	}

	/**
	 * Sends a message to the software.
	 * 
	 * @param messageType
	 *            The message type to send
	 * @param ambulanceID
	 *            The ambulance ID that sent the message
	 * @return true if correctly sent.
	 */
	public boolean send(MsgType messageType, int ambulanceID) {
		return rm.sendToSoftware(new RadioMessage(messageType, ambulanceID));
	}

	/**
	 * Sends a message to the software.
	 * 
	 * @param messageType
	 *            The message type to send
	 * @param ambulanceID
	 *            The ambulance ID that sent the message
	 * @param ambulanceType
	 *            The ambulance type of the ambulance that sent the message
	 * @return true if correctly sent.
	 */
	public boolean send(MsgType messageType, int ambulanceID, AmbType ambulanceType) {
		return rm.sendToSoftware(new RadioMessage(messageType, ambulanceID, ambulanceType));
	}

	/**
	 * Sends a message containing a position to the software.
	 * 
	 * @param position
	 *            The position to send
	 * @param ambulanceID
	 *            The receiving ambulance ID
	 * @return true if correctly sent, false otherwise.
	 */
	public boolean sendAmbulancePosition(MapPosition position, int ambulanceID) {
		return rm.sendToSoftware(new RadioMessage(position, ambulanceID));
	}

	/**
	 * Called by the RadioManager when a Radio message was send to the environment.
	 * 
	 * @param message
	 *            the received message
	 * @return true if correctly received, false otherwise.
	 */
	public boolean receive(RadioMessage message) {
		return receivingQueue.add(message);
	}

	/**
	 * Return the oldest unread RadioMessage received. Blocks until at least one
	 * unread RadioMessage exists.
	 * 
	 * @return The received RadioMessage.
	 * @throws InterruptedException
	 */
	public RadioMessage listen(long delay) throws InterruptedException {

		return receivingQueue.poll(delay, TimeUnit.MILLISECONDS);

	}

	/**
	 * 
	 * @return the ID of the Radio's ambulance
	 */
	public int getAmbID() {
		return ambID;
	}

}
